home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume2 / dots2 < prev    next >
Encoding:
Internet Message Format  |  1987-09-19  |  63.7 KB

  1. Path: uunet!husc6!bbn!rochester!rutgers!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request
  2. From: games-request@tekred.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v02i051:  dots2 - visual dots and crosses game, version 2
  5. Message-ID: <1618@tekred.TEK.COM>
  6. Date: 17 Sep 87 23:40:09 GMT
  7. Sender: billr@tekred.TEK.COM
  8. Lines: 2347
  9. Approved: billr@tekred.TEK.COM
  10.  
  11. Submitted by: Dan Heller <island!argv%maui@sun.com>
  12. Comp.sources.games: Volume 2, Issue 51
  13. Archive-name: dots2
  14.  
  15.     [Here is a revised version of the dots game that Dan
  16.      submitted earlier.       -br]
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of shell archive."
  26. # Contents:  Makefile board.c comp.c comp2.c dots.doc dots.h findem.c
  27. #   main.c menu.c misc.c person.c save.c score.c sockt.c
  28. # Wrapped by billr@tekred on Thu Sep 17 16:35:24 1987
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f Makefile -a "${1}" != "-c" ; then 
  31.   echo shar: Will not over-write existing file \"Makefile\"
  32. else
  33. echo shar: Extracting \"Makefile\" \(2852 characters\)
  34. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  35. X#
  36. X# Makefile for dots
  37. X#
  38. X#  Dots and Boxes -- the program for UNIX was programmed by Dan Heller and
  39. X#     Don Hatch Spring, 1984 with further developments continually.
  40. X#  Sockets Implemented by Dan Heller in May, 1985.
  41. X#
  42. X# This program was originally written on a PDP-11 under UNIX V7.
  43. X#
  44. X# If you are on a berkeley unix system, then you should have -DBSD defined
  45. X# below and use the appropriate OBJS (see notes below).  If you are using
  46. X# a system-V unix then you should define -DSYSV and use those OBJS.
  47. X#
  48. X# Installation is so easy that there's no need for a README or anything,
  49. X# Be sure to edit dots.h and change some of the constants to whatever
  50. X# pathnames you'd like them to be and note VPRINTF and DESTDIR are defined
  51. X# here.
  52. X#
  53. X# Rules for defining VPRINTF:
  54. X# 1) you are a system-v (xenix or otherwise) machine.
  55. X# 2) you are on a sun running 3.0 or higher.
  56. X# DO NOT define VPRINTF if you are on a vax or running 4.[23] or something.
  57. X# If you are unsure, try:
  58. X#  % ar t /lib/libc.a | grep vprintf
  59. X# If you don't get output, you don't have it.  If you do have it, you'll
  60. X# get several lines of output (vprintf.o vsprintf.o).
  61. X#
  62. X# This code is intended for public consumption and modifications are
  63. X# enoucraged.  If you do make mods, I'd love to hear about them and
  64. X# include in later releases (interest providing).
  65. X#
  66. X# Since everything includes dots.h a make depend is senseless. If you
  67. X# make changes to defines, grep the files to note which are affected
  68. X# and remake them.  If you change variables, use grep on .c files or use
  69. X# "nm" on the .o files to find which files use them.
  70. X#
  71. X# The file "dots.doc" has more information on how to play.
  72. X#
  73. X# comments, etc... to:  Dan Heller
  74. X#    island!argv@sun.com        argv@spam.istc.sri.com
  75. X#
  76. X# Thanx to Jay Libove for his port to XENIX (System-V)
  77. X# Thanx to Bruno Wolff for general bug fixes.
  78. X
  79. X# for xenix systems or (hopefully) any sys-v unix, use these CFLAGS and LDFLAGS
  80. X# CFLAGS=    -O -DSYSV -Ml -DVPRINTF
  81. X# LDFLAGS= -s -Ml
  82. X
  83. X# BSD systems should use these CFLAGS and  LDFLAGS
  84. XCFLAGS=    -O -DBSD
  85. XLDFLAGS= -s
  86. X
  87. XDESTDIR= /usr/games
  88. XLINTFLAGS= -bxah -Dlint
  89. XLIBES = -lcurses -ltermlib
  90. X
  91. XPROG=dots
  92. X
  93. XSRCS=main.c comp.c comp2.c board.c person.c misc.c menu.c save.c score.c \
  94. X     sockt.c findem.c
  95. X
  96. X# SYSV (xenix) *do not* use sockt.o and findem.o -- BSD systems *do use* them.
  97. X# OBJS=main.o comp.o comp2.o board.o person.o misc.o menu.o save.o score.o
  98. XOBJS=main.o comp.o comp2.o board.o person.o misc.o menu.o save.o score.o \
  99. X     sockt.o findem.o
  100. X
  101. X${PROG}: ${OBJS}
  102. X    @echo Loading...
  103. X    @cc ${LDFLAGS} ${OBJS} ${LIBES} -o ${PROG}
  104. X
  105. Xinstall: ${PROG}
  106. X    /bin/mv ${PROG} ${DESTDIR}/${PROG}
  107. X    chmod 711 ${DESTDIR}/${PROG}
  108. X
  109. Xtags:
  110. X    ctags dots.h ${SRCS}
  111. X
  112. Xclean:
  113. X    rm -f core ${OBJS} ${PROG}
  114. X
  115. Xlint:
  116. X    lint ${LINTFLAGS} ${SRCS}
  117. X
  118. Xtar:
  119. X    tar fcv DOTS Makefile dots.h $(SRCS) tags
  120. X
  121. Xshar:
  122. X    shar Makefile dots.doc dots.h $(SRCS) > dots.shar
  123. END_OF_Makefile
  124. if test 2852 -ne `wc -c <Makefile`; then
  125.     echo shar: \"Makefile\" unpacked with wrong size!
  126. fi
  127. # end of overwriting check
  128. fi
  129. if test -f board.c -a "${1}" != "-c" ; then 
  130.   echo shar: Will not over-write existing file \"board.c\"
  131. else
  132. echo shar: Extracting \"board.c\" \(3320 characters\)
  133. sed "s/^X//" >board.c <<'END_OF_board.c'
  134. X/*    board.c    routines that deal with the playing board's display or data */
  135. X
  136. X#include "dots.h"
  137. X
  138. Xsetup()
  139. X{
  140. X    Length = Width = 0;
  141. X    comptally = persontally = 0;
  142. X    xposit = 2, yposit = 1;
  143. X
  144. X    mvprintw(LINES - 6, 0, "Enter LENGTH of board (%d - %d).",
  145. X     (level == DUMB)? MINL : H_MINL, MAXL);
  146. X    do  {
  147. X    mvaddstr(LINES - 4, 0, "->> "), clrtoeol(), refresh();
  148. X    x_start = COLS / 2 - (Length = get_dimensions()) * 2;
  149. X    } while (Length > MAXL || (level == DUMB && Length < MINL) ||
  150. X    (level != DUMB && Length < H_MINL));
  151. X
  152. X    mvprintw(LINES - 6, 0, "Enter WIDTH of board (%d - %d).",
  153. X    (level==DUMB)? MINW:H_MINW, MAXW), clrtoeol();
  154. X    do  {
  155. X    mvaddstr(LINES - 4, 0, "->> "), clrtoeol(), refresh();
  156. X    y_start = LINES / 2 - (Width = get_dimensions());
  157. X    } while (Width > MAXW || (level == DUMB && Width < MINW) ||
  158. X    (level != DUMB && Width < H_MINW));
  159. X
  160. X    mvprintw(LINES - 6, 0, "Length is %d, width is %d.", Length, Width);
  161. X    clrtoeol(), refresh();
  162. X    if (mode == INTERACTIVE)
  163. X    mvprintw(LINES-4, 0,
  164. X        "Your boxes will be initialed with \"%c\"",Initial[US]), clrtoeol();
  165. X    msg("Hit any key to continue. ");
  166. X    getchar();
  167. X}
  168. X
  169. Xfree_board()
  170. X{
  171. X    register int x, y;
  172. X
  173. X    for (x = 0; x <= Length * 2; ++x)
  174. X    for (y = 0; y <= Width * 2; ++y)
  175. X        board[x][y] = FREE;
  176. X    no_good_moves = control_already_established = 0;
  177. X}
  178. X
  179. X/* special signal catcher for get dimensions prompt.  If user got here
  180. X * by mistake (entering a level unintentionally), he can ^C to get back
  181. X * to the main menu.  You can't get here without going thru the menu,
  182. X * so don't worry about getting a longjump botch.  longjmp with value
  183. X * of 2 to indicate that it's not necessary to redisplay the menu.
  184. X */
  185. Xdont_ask()
  186. X{
  187. X    (void) signal(SIGINT, onintr);
  188. X    longjmp(menu_jmp, 2);
  189. X}
  190. X
  191. Xget_dimensions()
  192. X{
  193. X    char          string[10];
  194. X    register char   c;
  195. X    register int    place_on_line = 0, x = 0;
  196. X
  197. X    (void) signal(SIGINT, dont_ask);
  198. X
  199. X    string[0] = '\0';
  200. X
  201. X    move(LINES - 4, 4), clrtoeol();
  202. X    refresh();
  203. X    while ((c = getchar()) != '\n') {
  204. X    if (c == erase_char || c == '\027')
  205. X        if (place_on_line != 0) {
  206. X        string[--x] = '\0';
  207. X        --place_on_line;
  208. X        addstr("\b \b"); 
  209. X        refresh();
  210. X        } else
  211. X        continue;
  212. X    else if (isdigit(c)) {
  213. X        if (place_on_line == 4)
  214. X        continue;
  215. X        place_on_line++;
  216. X        addch(string[x++] = c);
  217. X        refresh();
  218. X    }
  219. X    }
  220. X    string[x] = '\0';
  221. X    (void) signal(SIGINT, onintr);
  222. X    return atoi(string);
  223. X}
  224. X
  225. Xdrawboard()
  226. X{
  227. X    register int x, y;
  228. X
  229. X    clear();
  230. X    for (y = 1; y < 2 * Width; y++)
  231. X    for (x = 1; x < 2 * Length; x++) {
  232. X        move(y_start + (y - 1), x_start + (2 * x - 2));
  233. X        if (iseven(x) && isodd(y) && board[x][y] == USED)
  234. X        addstr("\b---\b\b");
  235. X        if (iseven(y) && isodd(x) && board[x][y] == USED)
  236. X        addch('|');
  237. X        else if (iseven(x) && iseven(y) && closure(GOOD, x, y) == 4)
  238. X        putinitial(x, y, board[x][y]);
  239. X        else if (isodd(x) && isodd(y))
  240. X        addch('*');
  241. X    }
  242. X    if (mode == TWOPLAYER) {
  243. X    mvaddstr(LINES - 3, 0, "Your Messages: ");
  244. X    mvprintw(LINES - 2, 0, "%s's Messages: ", opponent);
  245. X    }
  246. X}
  247. X
  248. Xchlevel(c)
  249. X{
  250. X    if (!sure(c))
  251. X    return;
  252. X    level = (level + 1) % 3;
  253. X    bottom_line();
  254. X}
  255. X
  256. Xsure(c)
  257. Xchar c;
  258. X{
  259. X    register int   count;
  260. X    register char  C;
  261. X
  262. X    for (count = 0; count <= 3; ++count)
  263. X    if ((C = getchar()) != c) {
  264. X        ungetc(C, stdin);
  265. X        return FALSE;
  266. X    }
  267. X    return TRUE;
  268. X}
  269. END_OF_board.c
  270. if test 3320 -ne `wc -c <board.c`; then
  271.     echo shar: \"board.c\" unpacked with wrong size!
  272. fi
  273. # end of overwriting check
  274. fi
  275. if test -f comp.c -a "${1}" != "-c" ; then 
  276.   echo shar: Will not over-write existing file \"comp.c\"
  277. else
  278. echo shar: Extracting \"comp.c\" \(8116 characters\)
  279. sed "s/^X//" >comp.c <<'END_OF_comp.c'
  280. X/*    COMP.C    */
  281. X
  282. X#include "dots.h"
  283. X
  284. Xcompmove()
  285. X{
  286. X    bottom_line();
  287. X    close_boxes();
  288. X    if (!board_is_full())
  289. X    if (!find_good_move(GOOD))
  290. X        force_move();
  291. X}
  292. X
  293. Xclose_boxes()
  294. X{
  295. X    Bingo.x = Bingo.y = 0;
  296. X    dX_found = 0;
  297. X    if (level == DUMB || cntrl_not_established() || find_good_move(BAD))
  298. X    close_EVERYTHING();
  299. X    else
  300. X    first_pass();
  301. X}
  302. X
  303. Xfind_good_move(BorG)
  304. Xint BorG;
  305. X{
  306. X    int x, y, xcount, ycount, x1, y1, x2, y2;
  307. X
  308. X    if (no_good_moves)
  309. X    return (0);
  310. X    if (BorG == GOOD && level == KILLER && kill_4_loops())
  311. X    return (1);
  312. X    for (xcount = 1, x = random() % (2 * Length - 1) + 1; xcount < Length * 2;
  313. X    xcount++, x = x % (2 * Length - 1) + 1)
  314. X    for (ycount = 1, y = random() % (2 * Width - 1) + 1; ycount < Width * 2;
  315. X        ycount++, y = y % (2 * Width - 1) + 1) {
  316. X        if (iseven(x + y))
  317. X        continue;
  318. X        if (board[x][y] == USED)
  319. X        continue;
  320. X        find_adj_squares(x, y, &x1, &y1, &x2, &y2);
  321. X        if (closure(GOOD, x1, y1) == 2)
  322. X        continue;
  323. X        if (closure(GOOD, x2, y2) == 2)
  324. X        continue;
  325. X        if (BorG == GOOD) {
  326. X        xposit = x, yposit = y;
  327. X        (void) entermove();
  328. X        }
  329. X        return (1);
  330. X    }
  331. X    no_good_moves = 1;
  332. X    return (0);
  333. X}
  334. X
  335. X/********************************************************************\
  336. X|*   check all dots and ruins potential 4 loops.                    *|
  337. X|*                                                                  *|
  338. X|*      Want to prevent:      Find these:   Before they turn into:  *|
  339. X|*         *---*---*            *---*   *         *---*   *         *|
  340. X|*         |       |            |                |                 *|
  341. X|*         *   *   *            *   *   *         *   *   *         *|
  342. X|*         |       |                      |        *|
  343. X|*         *---*---*            *   *---*         *   *---*         *|
  344. X|*   Because 4 loops lose points and #3 guarantees 4-loops          *|
  345. X\********************************************************************/
  346. X
  347. Xkill_4_loops()
  348. X{
  349. X    int x, y, x1, y1, x2, y2, dx, dy, xcheck, ycheck;
  350. X
  351. X    for (x = 3; x <= 2 * Length - 3; x += 2)
  352. X    for (y = 3; y <= 2 * Width - 3; y += 2) {
  353. X        if (closure(GOOD, x, y))
  354. X        continue;    /* a line is connected to dot */
  355. X        for (dx = -1; dx <= 1; dx += 2)
  356. X        for (dy = -1; dy <= 1; dy += 2)
  357. X            if (closure(GOOD, x + dx, y + dy) == 2)
  358. X            if (closure(GOOD, x - dx, y - dy) == 1) {
  359. X                xcheck = x - dx, ycheck = y;
  360. X                do_twice
  361. X                {
  362. X                find_adj_squares(xcheck, ycheck, &x1, &y1, &x2, &y2);
  363. X                if (closure(GOOD, x1, y1) != 2 && closure(GOOD, x2, y2) != 2) {
  364. X                    xposit = xcheck, yposit = ycheck;
  365. X                    (void) entermove();
  366. X                    return (1);
  367. X                } else
  368. X                    xcheck = x, ycheck = y - dy;
  369. X                }
  370. X            }
  371. X    }
  372. X    return (0);
  373. X}
  374. X
  375. Xforce_move()
  376. X{
  377. X    int x, y, xcount, ycount, x1, y1, x2, y2;
  378. X    int Badness, bestx, besty, Bestbad = 1000, Besttype;
  379. X
  380. X    if (dX_found) {
  381. X    if (comptally + persontally + segflag == OPENEND ? 2 : 4 == (Length - 1) * (Width - 1)) {
  382. X        Bingo.x = Bingo.y = dX_found = 0;
  383. X        close_EVERYTHING();
  384. X        return;
  385. X    }
  386. X    if (segflag == OPENEND) {
  387. X        find_adj_squares(Bingo.x, Bingo.y, &x1, &y1, &x2, &y2);
  388. X        if (closure(GOOD, x1, y1) == 2 && closure(GOOD, x2, y2) == 2) {
  389. X        close_boxes();
  390. X        if (!board_is_full())
  391. X            force_move();
  392. X        return;
  393. X        }
  394. X    }
  395. X    xposit = Bingo.x;
  396. X    yposit = Bingo.y;
  397. X    (void) entermove();
  398. X    return;
  399. X    }
  400. X    for (xcount = 1, x = random() % (2 * Length - 1) + 1; xcount < Length * 2;
  401. X    xcount++, x = x % (2 * Length - 1) + 1)
  402. X    for (ycount = 1, y = random() % (2 * Width - 1) + 1; ycount < Width * 2;
  403. X        ycount++, y = y % (2 * Width - 1) + 1)
  404. X        if (isodd(x + y) && board[x][y] == FREE) {
  405. X        find_adj_squares(x, y, &x1, &y1, &x2, &y2);
  406. X        if (closure(GOOD, x1, y1) != 3 && closure(GOOD, x2, y2) != 3)
  407. X            if ((Badness = Howbad(GOOD, Bestbad, x, y)) < Bestbad) {
  408. X            Bestbad = Badness;
  409. X            bestx = x;
  410. X            besty = y;
  411. X            Besttype = segtype;
  412. X            }
  413. X        }
  414. X    if (Bestbad >= 2 && Besttype == OPENEND)
  415. X    goto_middle_of_path(GOOD, &bestx, &besty);
  416. X    xposit = bestx;
  417. X    yposit = besty;
  418. X    (void) entermove();
  419. X}
  420. X
  421. Xfirst_pass()
  422. X{
  423. X    int x, y, x1, y1, doubleX, doubleY;
  424. X    int Badness;
  425. X    int start_over;
  426. X
  427. X    do {
  428. X    start_over = 0;
  429. X    for (x = 2; x <= 2 * Length - 2 && !start_over; x += 2)
  430. X        for (y = 2; y <= 2 * Width - 2 && !start_over; y += 2)
  431. X        if (closure(GOOD, x, y) == 3) {
  432. X            x1 = x, y1 = y;
  433. X            goto_adj_free_line(GOOD, &x1, &y1);
  434. X            if (((Badness = Howbad(BAD, 1000, x1, y1)) == 2 &&
  435. X                segtype == OPENEND)
  436. X            || (Badness == 4 && segtype == CLOSEDEND)) {
  437. X            segflag = segtype;
  438. X            dX_found = 1;
  439. X            doubleX = x1;
  440. X            doubleY = y1;
  441. X            board[x1][y1] = USED;    /* temporarily */
  442. X            goto_next_square(GOOD, &doubleX, &doubleY);
  443. X            goto_adj_free_line(GOOD, &doubleX, &doubleY);
  444. X            Bingo.x = doubleX;
  445. X            Bingo.y = doubleY;
  446. X            board[x1][y1] = FREE;    /* SIGH */
  447. X            close_EVERYTHING();
  448. X            return;
  449. X            } else if (Badness <= 2) {
  450. X            xposit = x1, yposit = y1;
  451. X            entermove();
  452. X            } else {
  453. X            xposit = x1, yposit = y1;
  454. X            entermove();
  455. X            start_over = 1;
  456. X            }
  457. X        }
  458. X    }
  459. X    while (start_over);
  460. X}
  461. X
  462. Xclose_EVERYTHING()
  463. X{
  464. X    int x, y, x_check, y_check, moved;
  465. X
  466. X    do {
  467. X    moved = 0;
  468. X    for (x = 2; x <= 2 * Length - 2; x += 2)
  469. X        for (y = 2; y <= 2 * Width - 2; y += 2)
  470. X        if (closure(GOOD, x, y) == 3) {
  471. X            x_check = x, y_check = y;
  472. X            goto_adj_free_line(GOOD, &x_check, &y_check);
  473. X            /* at the end of the game, ignore this line! */
  474. X            if (!board_is_almost_full() && too_close(x_check, y_check))
  475. X            continue;
  476. X            xposit = x_check;
  477. X            yposit = y_check;
  478. X            entermove();
  479. X            moved = 1;
  480. X        }
  481. X    }
  482. X    while (moved);
  483. X}
  484. X
  485. XHowbad(BorG, Max, xmove, ymove)
  486. Xint BorG, Max, xmove, ymove;
  487. X{
  488. X    int x, y, x1, y1, x2, y2, moved, badtotal = 0;
  489. X
  490. X    for (x = 1; x < 2 * Length; x++)
  491. X    for (y = isodd(x) ? 2 : 1; y < 2 * Width; y += 2)
  492. X        badboard[x][y] = board[x][y];
  493. X    if (BorG == GOOD)
  494. X    badboard[xmove][ymove] = USED;
  495. X    segtype = OPENEND;
  496. X
  497. X    do_twice {
  498. X    x = xmove;
  499. X    y = ymove;
  500. X    do {
  501. X        moved = 0;
  502. X        if (!goto_next_square(BAD, &x, &y))
  503. X        break;
  504. X        goto_adj_free_line(BAD, &x, &y);
  505. X        badboard[x][y] = USED;
  506. X        moved = 1;
  507. X        find_adj_squares(x, y, &x1, &y1, &x2, &y2);
  508. X        if (closure(BAD, x1, y1) == 4 && closure(BAD, x2, y2) == 4)
  509. X        badtotal++, segtype = CLOSEDEND;    /* add extra for two
  510. X                             * sides */
  511. X        badtotal++;
  512. X        if (badtotal >= Max)
  513. X        return (Max);
  514. X    }
  515. X    while (moved == 1);
  516. X    }
  517. X    return (badtotal);
  518. X}
  519. X
  520. X/***********************************************************************\
  521. X|*  This procedure returns true if the line passed is on either of the *|
  522. X|*  boxes next to Bingo.                                               *|
  523. X\***********************************************************************/
  524. X
  525. Xtoo_close(x, y)
  526. Xint x, y;
  527. X{
  528. X    if (abs(x - Bingo.x) == 1 && abs(y - Bingo.y) == 1) {    /* REAL close */
  529. X    if (isodd(Bingo.x)) {    /* Bingo is vertical  */
  530. X        if (closure(GOOD, x, Bingo.y) == 2)
  531. X        return (1);
  532. X    } else {    /* Bingo is horizontal */
  533. X        if (closure(GOOD, Bingo.x, y) == 2)
  534. X        return (1);
  535. X    }
  536. X    }
  537. X    if (isodd(Bingo.x)) {    /* Bingo is vertical  */
  538. X    if ((abs(x - Bingo.x) == 2 && y == Bingo.y)
  539. X        && (closure(GOOD, (x + Bingo.x) / 2, y) == 2))
  540. X        return (1);
  541. X    } else {        /* Bingo is horizontal */
  542. X    if ((abs(y - Bingo.y) == 2 && x == Bingo.x)
  543. X        && (closure(GOOD, x, (y + Bingo.y) / 2) == 2))
  544. X        return (1);
  545. X    }
  546. X    return (0);
  547. X}
  548. X
  549. X/***************************************************************************\
  550. X|* This function decides if there are still more open-ended paths of       *|
  551. X|* length two or less still on the board. If there are, it returns 1, else *|
  552. X|* 0.                                                                      *|
  553. X\***************************************************************************/
  554. X
  555. Xcntrl_not_established()
  556. X{
  557. X    int x, y, x1, y1, x2, y2;
  558. X
  559. X    if (control_already_established)
  560. X    return (0);
  561. X    for (x = 1; x < 2 * Length; x++)
  562. X    for (y = isodd(x) ? 2 : 1; y < 2 * Width; y += 2)
  563. X        if (board[x][y] == FREE)
  564. X        if (Howbad(GOOD, 3, x, y) <= 2 && segtype == OPENEND) {
  565. X            find_adj_squares(x, y, &x1, &y1, &x2, &y2);
  566. X            if (closure(GOOD, x1, y1) <= 2 && closure(GOOD, x2, y2) <= 2)
  567. X            return (1);
  568. X        }
  569. X    control_already_established = 1;
  570. X    return (0);
  571. X}
  572. END_OF_comp.c
  573. if test 8116 -ne `wc -c <comp.c`; then
  574.     echo shar: \"comp.c\" unpacked with wrong size!
  575. fi
  576. # end of overwriting check
  577. fi
  578. if test -f comp2.c -a "${1}" != "-c" ; then 
  579.   echo shar: Will not over-write existing file \"comp2.c\"
  580. else
  581. echo shar: Extracting \"comp2.c\" \(2257 characters\)
  582. sed "s/^X//" >comp2.c <<'END_OF_comp2.c'
  583. X/*    COMP2.C    */
  584. X
  585. X#include "dots.h"
  586. X
  587. Xgoto_next_square(BorG, x, y)    /* returns 1 if there is one, 0 if not */
  588. Xint BorG, *x, *y;
  589. X{
  590. X    int x1, y1, x2, y2;
  591. X
  592. X    find_adj_squares(*x, *y, &x1, &y1, &x2, &y2);
  593. X    if (x1 != NULL && closure(BorG, x1, y1) == 3) {
  594. X    *x = x1, *y = y1;
  595. X    return (1);
  596. X    }
  597. X    if (x2 != NULL && closure(BorG, x2, y2) == 3) {
  598. X    *x = x2, *y = y2;
  599. X    return (1);
  600. X    }
  601. X    return (0);
  602. X}
  603. X
  604. Xfind_adj_squares(x, y, x1, y1, x2, y2)
  605. Xint x, y, *x1, *y1, *x2, *y2;
  606. X{
  607. X    if (isodd(x)) {    /* Vertical line */
  608. X    *x1 = x - 1;
  609. X    *y1 = y;
  610. X    *x2 = x + 1;
  611. X    *y2 = y;
  612. X    } else {        /* Horizontal line */
  613. X    *x1 = x;
  614. X    *y1 = y - 1;
  615. X    *x2 = x;
  616. X    *y2 = y + 1;
  617. X    }
  618. X    if (!is_on_board(*x1, *y1))
  619. X    *x1 = NULL, *y1 = NULL;
  620. X    if (!is_on_board(*x2, *y2))
  621. X    *x2 = NULL, *y2 = NULL;
  622. X}
  623. X
  624. Xgoto_adj_free_line(BorG, x, y)
  625. Xint BorG;
  626. Xint *x, *y;
  627. X{
  628. X    int xtemp, ytemp;
  629. X
  630. X    for (xtemp = *x - 1; xtemp <= *x + 1; xtemp += 2)
  631. X    if ((BorG == BAD ? badboard[xtemp][*y] : board[xtemp][*y]) == FREE) {
  632. X        *x = xtemp;
  633. X        return;
  634. X    }
  635. X    for (ytemp = *y - 1; ytemp <= *y + 1; ytemp += 2)
  636. X    if (board[*x][ytemp] == FREE)
  637. X        if (((BorG == BAD)? badboard[*x][ytemp] : board[*x][ytemp])
  638. X            == FREE) {
  639. X        *y = ytemp;
  640. X        return;
  641. X        }
  642. X    printf("You fucked up, buddy!");
  643. X    fflush(stdout);
  644. X    die();
  645. X}
  646. X
  647. X/*****************************************************************************\
  648. X|*  right now, this function doesn't actually go to the middle of a path,    *|
  649. X|*  it simply goes one line away from the edge. If the length of the path is *|
  650. X|*  two, the effect is the same.                                             *|
  651. X\*****************************************************************************/
  652. Xgoto_middle_of_path(BorG, x, y)
  653. Xint BorG, *x, *y;
  654. X{
  655. X    int origx, origy, x1, y1, x2, y2;
  656. X
  657. X    find_adj_squares(*x, *y, &x1, &y1, &x2, &y2);
  658. X    if (closure(BorG, x1, y1) == 2 && closure(BorG, x2, y2) == 2)
  659. X    return;        /* you're sitting on it to begin with */
  660. X    origx = *x, origy = *y;
  661. X    if (BorG == GOOD)
  662. X    board[origx][origy] = USED;
  663. X    else
  664. X    badboard[origx][origy] = USED;
  665. X    /* Temporarily */
  666. X    goto_next_square(BorG, x, y);
  667. X    goto_adj_free_line(BorG, x, y);
  668. X
  669. X    if (BorG == GOOD)
  670. X    board[origx][origy] = FREE;
  671. X    else
  672. X    badboard[origx][origy] = FREE;
  673. X    /* SIGH! */
  674. X}
  675. END_OF_comp2.c
  676. if test 2257 -ne `wc -c <comp2.c`; then
  677.     echo shar: \"comp2.c\" unpacked with wrong size!
  678. fi
  679. # end of overwriting check
  680. fi
  681. if test -f dots.doc -a "${1}" != "-c" ; then 
  682.   echo shar: Will not over-write existing file \"dots.doc\"
  683. else
  684. echo shar: Extracting \"dots.doc\" \(3304 characters\)
  685. sed "s/^X//" >dots.doc <<'END_OF_dots.doc'
  686. X                         . . .  D  O  T  S  . . .
  687. X
  688. X
  689. X       For points, create squares like this:
  690. X
  691. X                                *---*
  692. X                                | X |
  693. X                                *---*
  694. X
  695. X       Whoever has more squares at the end of the game wins.
  696. X       When a square is won, that player's initial will be
  697. X       put inside the square as shown. 
  698. X
  699. X       To move the cursor, use one of three ways:
  700. X       The "rogue/vi" keys, the number keys or the 
  701. X       keys surrounding the 's'.
  702. X
  703. X       rogue:                         's':                       numbers
  704. X        
  705. X        y k u                        q w e                        7 8 9
  706. X       h     l                      a  s  d                      4     6
  707. X        b j n                        z x c                        1 2 3
  708. X
  709. X       The circle represents which direction you would move away from
  710. X       where the cursor would currently be located.  The numbers are
  711. X       good for terminals that have separate number key pads. The RETURN
  712. X       key or the space-bar will enter a move at the current cursor position.
  713. X
  714. X       When a player enters a move, if he did NOT close any boxes, then
  715. X       it is the other player's turn.  If the player DOES close a box, it
  716. X       remains that players turn and he MUST move again even if he doesn't
  717. X       have another scoring move.
  718. X
  719. X       ^L   will redraw the screen if it gets messed up (or try ^\).
  720. X       'S'  will save your game.
  721. X
  722. X       If you are playing the two player game, that is, another human,
  723. X       not the computer, use the ESCAPE key to 'talk' to the other player.
  724. X       You can ONLY do this when it's your turn. You cannot save games when
  725. X       playing someone else.  There is no high score file for two player games.
  726. X
  727. X       Command line arguments:
  728. X
  729. X       You can see the high-scores without playing by typing:
  730. X
  731. X       % dots -s
  732. X
  733. X       You can restart a saved game by typing:
  734. X
  735. X       % dots -r
  736. X          which will read "dots.save" from your home directory or:
  737. X
  738. X       % dots -r saved_file_name
  739. X       if you've saved it as something other than "dots.save".
  740. X       Be sure to give the full pathname if the file is not in
  741. X       your current directory.
  742. X
  743. X       You can avoid the menu by giving the following information on
  744. X       the command line:
  745. X
  746. X       % dots LENGTH WIDTH LEVEL [C]
  747. X
  748. X          where "length", "width", and "level" are values to use
  749. X          for the length and width of the playing board and level
  750. X      is the level of difficulty to play at (0-3).
  751. X          'C' is the initial to use if you don't want the first
  752. X      letter of your account name in the middle of your squares.
  753. X
  754. X       Example:
  755. X
  756. X       % dots 5 9 0 F
  757. X
  758. X       will play an easy game on a 5 X 9 board and your boxes will be
  759. X       initialized with 'F'.
  760. X
  761. X
  762. X       There is also a way to play others on the system. In the menu,
  763. X       choose the '7' item.  From the command line (avoiding the menu),
  764. X       type:
  765. X
  766. X       % dots 2 login name [tty]
  767. X
  768. X       You may specify the tty if the same user is logged in more than
  769. X       once.  You would use the same format to respond to someone else's
  770. X       request to play you.  When you send (receive) a request, the
  771. X       challenged will get a message every 30 seconds until that user replys 
  772. X       or until the challenger terminates (just like talk).
  773. X
  774. X
  775. END_OF_dots.doc
  776. if test 3304 -ne `wc -c <dots.doc`; then
  777.     echo shar: \"dots.doc\" unpacked with wrong size!
  778. fi
  779. # end of overwriting check
  780. fi
  781. if test -f dots.h -a "${1}" != "-c" ; then 
  782.   echo shar: Will not over-write existing file \"dots.h\"
  783. else
  784. echo shar: Extracting \"dots.h\" \(2656 characters\)
  785. sed "s/^X//" >dots.h <<'END_OF_dots.h'
  786. X/*    dots.h    */
  787. X
  788. X#include <curses.h>
  789. X#include <sys/types.h>
  790. X#include <sys/ioctl.h>
  791. X#if defined(lint) && defined(BSD)
  792. X#include <sys/uio.h>
  793. X#endif /* lint && BSD */
  794. X#ifdef BSD
  795. X#include <sys/socket.h>
  796. X#endif /* BSD */
  797. X#include <ctype.h>
  798. X#include <signal.h>
  799. X#include <setjmp.h>
  800. X#ifdef BSD
  801. X#include <strings.h>
  802. X#else
  803. X#include <string.h>
  804. X#endif /* BSD */
  805. X
  806. X#ifdef BSD
  807. Xextern char *sprintf();
  808. X#else
  809. Xextern int sprintf();
  810. X#endif /* BSD */
  811. X
  812. X/* Most BSD systems don't have vprintf, but sun versions 3.0 and up do have it.
  813. X * If you're system doesn't have it, comment out the define line. System-V
  814. X * systems do have it.
  815. X */
  816. X#ifdef SYSV
  817. X#define VPRINTF
  818. X#endif /* SYSV */
  819. X
  820. X#ifdef SYSV
  821. X#define SIGCHLD SIGCLD
  822. X#define srandom srand
  823. X#define random rand
  824. X#define index strchr
  825. X#define rindex strrchr
  826. X#endif /* SYSV */
  827. X
  828. X#define PRIZE        "cigar"
  829. X#define DOCFILE        "/usr/games/lib/dots/dots.doc"
  830. X#define SAVE_FILE    "dots.save"
  831. X#define SCOREFILE    "/usr/games/lib/dots/dots.scores" /* should be full pathname */
  832. X#define version        "Dots version 2.0"
  833. X
  834. X#define when        break;case
  835. X#define otherwise    break;default
  836. X#define Upper(c)    (c = islower(c) ? toupper(c) : c)
  837. X#define Lower(c)    (c = isupper(c) ? tolower(c) : c)
  838. X#define max(a,b)    ((a) > (b) ? (a) : (b))
  839. X#define min(a,b)    ((a) > (b) ? (b) : (a))
  840. X#define erase_char    '\b'
  841. X
  842. X#define ESC        '\033'
  843. X#define DEMO        0
  844. X#define INTERACTIVE    1
  845. X#define TWOPLAYER    2
  846. X#define GOOD        0
  847. X#define BAD        1
  848. X#define DUMB        0
  849. X#define HARD        1
  850. X#define KILLER        2
  851. X#define FREE        0
  852. X#define USED        1
  853. X#define CLOSEDEND    0  /* used for segtype for creating doublecrosses */
  854. X#define OPENEND        1    /* ditto */
  855. X#define MAXL        (COLS / 4)
  856. X#define MAXW        (LINES / 2)
  857. X#define H_MINL        10
  858. X#define H_MINW        10
  859. X#define MINL        4
  860. X#define MINW        4
  861. X#define US        0
  862. X#define THEM        1
  863. X#define SAVE        0
  864. X#define LOAD        1
  865. X#define isodd(a)    ((a)%2)
  866. X#define iseven(a)    (!isodd(a))
  867. X#define ism4(a)        (!((a)%4))
  868. X#define do_twice    for(twicecount=1;twicecount<=2;++twicecount)
  869. X
  870. Xint
  871. X    board[120][120],
  872. X    badboard[120][120],
  873. X    persontally, comptally,
  874. X    Length, Width,
  875. X    xposit, yposit,
  876. X    x_start, y_start,
  877. X    mover,        /* 0 is person/US, 1 is computer/THEM */
  878. X    twicecount,
  879. X    no_good_moves,
  880. X    control_already_established,
  881. X    segtype,    /* OPENEND or CLOSEDEND ; set everytime Howbad is called */
  882. X    dX_found,
  883. X    segflag,
  884. X    mode,
  885. X    level,
  886. X    sd,            /* socket descriptor */
  887. X    jmpbuf_set;
  888. X
  889. Xstruct {
  890. X    int x, y;
  891. X}   Bingo;
  892. X
  893. Xstruct tchars tchars;
  894. X
  895. Xchar *opponent, prize[30], save_file[50], *getenv();
  896. Xchar Initial[2], *username;
  897. Xint onintr(), redraw(), oops();
  898. X
  899. X/* jump to the menu so there's no big stacks (supposedly) */
  900. Xjmp_buf menu_jmp;
  901. X
  902. Xextern int errno;
  903. Xextern char *sys_errlist[], *sys_siglist[];
  904. END_OF_dots.h
  905. if test 2656 -ne `wc -c <dots.h`; then
  906.     echo shar: \"dots.h\" unpacked with wrong size!
  907. fi
  908. # end of overwriting check
  909. fi
  910. if test -f findem.c -a "${1}" != "-c" ; then 
  911.   echo shar: Will not over-write existing file \"findem.c\"
  912. else
  913. echo shar: Extracting \"findem.c\" \(1475 characters\)
  914. sed "s/^X//" >findem.c <<'END_OF_findem.c'
  915. X/* findem.c   find the login of the person we wanna play */
  916. X
  917. X#include "dots.h"
  918. X#include <sys/stat.h>
  919. X#include <sgtty.h>
  920. X#include <utmp.h>
  921. X
  922. X#define UTMP          "/etc/utmp"
  923. X
  924. Xstruct utmp utmp_buf;
  925. Xstruct stat stat_buf;
  926. Xstruct sgttyb sgtty_buf;
  927. X
  928. Xint fd;
  929. X
  930. Xfindem(argc, argv)
  931. Xchar **argv;
  932. X{
  933. X    char *ttyname(), to_tty[13];
  934. X    register char *login = argv[2], *where = "", *ourtty = ttyname(0) + 5;
  935. X    register FILE *recipient;
  936. X
  937. X    if (argc > 3)
  938. X    where = argv[3];
  939. X    if (!strcmp(where, ourtty)) {
  940. X    fprintf(stderr, "You can't play yourself.\n");
  941. X    return 0;
  942. X    }
  943. X    if ((fd = open(UTMP, 0)) == -1) {
  944. X    perror(UTMP);
  945. X    return 0;
  946. X    }
  947. X
  948. X    while (read(fd, (char *) &utmp_buf, sizeof(utmp_buf)))
  949. X    if (!strcmp(utmp_buf.ut_name, login) &&
  950. X       (*where && !strcmp(utmp_buf.ut_line, where) ||
  951. X       (!*where && strcmp(where, ourtty))))
  952. X        break;
  953. X
  954. X    (void) close(fd);
  955. X    if (strcmp(login, utmp_buf.ut_name)) {
  956. X    fprintf(stderr, "%s is not logged in.", login);
  957. X    return 0;
  958. X    }
  959. X    if (*where && strcmp(where, utmp_buf.ut_line)) {
  960. X    fprintf(stderr, "%s is not logged in on %s.\n", login, where);
  961. X    return 0;
  962. X    }
  963. X
  964. X    (void) sprintf(to_tty, "/dev/%s", utmp_buf.ut_line);
  965. X    if (!(recipient = fopen(to_tty, "w"))) {
  966. X    perror(to_tty);
  967. X    fprintf(stderr, "%s: Can't ask %s to play.\n", argv[0], argv[2]);
  968. X    return 0;
  969. X    }
  970. X    setuid(getuid());    /* turns off set-uid attribute once tty is opened */
  971. X    setgid(getgid());    /* probably isn't necessary most of the time */
  972. X
  973. X    return invite(recipient);
  974. X}
  975. END_OF_findem.c
  976. if test 1475 -ne `wc -c <findem.c`; then
  977.     echo shar: \"findem.c\" unpacked with wrong size!
  978. fi
  979. # end of overwriting check
  980. fi
  981. if test -f main.c -a "${1}" != "-c" ; then 
  982.   echo shar: Will not over-write existing file \"main.c\"
  983. else
  984. echo shar: Extracting \"main.c\" \(5274 characters\)
  985. sed "s/^X//" >main.c <<'END_OF_main.c'
  986. X/*    MAIN.C    */
  987. X
  988. X#include "dots.h"
  989. X
  990. Xchar *error_msg[] = {
  991. X    "usages:\n",
  992. X    "%s -s        gives top scores.\n",
  993. X    "%s -d        reads the directions\n",
  994. X    "%s -r [file]    restart saved game (from file if given).\n",
  995. X    "%s L W D [C]    plays a game using integer arguments as\n",
  996. X    "            Length, Width and Difficulty levels, respectively.\n",
  997. X    "            'C' is inital for boxes.\n",
  998. X    "%s 2 user [tty]    send request/reply to play someone else (2-user).\n",
  999. X    "\nsetenv DOTSOPTS \"name=whoareyou,savefile=path,initial=X,prize=whatever\"\n",
  1000. X    0
  1001. X};
  1002. X
  1003. Xchar *getusername();
  1004. X
  1005. Xbus_n_seg(sig)
  1006. X{
  1007. X    if (sig == SIGBUS)
  1008. X    fprintf(stderr, "Bus error.\n");
  1009. X    else
  1010. X    fprintf(stderr, "Segmentation Fault.\n");
  1011. X    die();
  1012. X}
  1013. X
  1014. Xmain(argc, argv)
  1015. Xint argc;
  1016. Xchar **argv;
  1017. X{
  1018. X    register char *p;
  1019. X    extern char *UP;
  1020. X
  1021. X    setbuf(stdout, (char *)NULL);
  1022. X    setbuf(stderr, (char *)NULL);
  1023. X
  1024. X    username = getusername();
  1025. X
  1026. X    savetty();
  1027. X    initscr();
  1028. X
  1029. X    (void) signal(SIGBUS,  bus_n_seg);
  1030. X    (void) signal(SIGSEGV, bus_n_seg);
  1031. X    (void) signal(SIGINT,  onintr);
  1032. X    (void) signal(SIGPIPE, onintr);
  1033. X    (void) signal(SIGCHLD, SIG_IGN); /* to return from shell esc */
  1034. X    (void) signal(SIGQUIT, redraw);
  1035. X
  1036. X    if (argc > 1 && argv[1][0] == '-' && argv[1][1] != 'r')
  1037. X    if (argv[1][1] == 'd')
  1038. X        readinst(1), exit(0);
  1039. X    else if (argv[1][1] == 's')
  1040. X        high_score(TRUE, FALSE), die();
  1041. X    else if (argv[1][1] == 'x')
  1042. X        high_score(TRUE, TRUE), die();
  1043. X    else
  1044. X        do_error(argv[0]), die();
  1045. X
  1046. X    if (COLS < 4 * H_MINL || LINES < 2 * H_MINW) {
  1047. X    printf("Window must be at least %d by %d.\n", 4 * H_MINL, 2 * H_MINW);
  1048. X    die();
  1049. X    }
  1050. X    if (!*UP) {
  1051. X    printf("You need cursor movement capability on your terminal.\n");
  1052. X    die();
  1053. X    }
  1054. X
  1055. X    srandom(getpid());
  1056. X    mover = US, Initial[THEM] = '$';
  1057. X    getopts();
  1058. X    noecho(), crmode();
  1059. X
  1060. X    if (argc > 1)
  1061. X    parse_command(argc, argv);
  1062. X    else
  1063. X    menu();
  1064. X}
  1065. X
  1066. Xdo_error(arg)
  1067. Xchar *arg;
  1068. X{
  1069. X    int count = 0;
  1070. X
  1071. X    while (error_msg[count])
  1072. X    fprintf(stderr, error_msg[count++], arg);
  1073. X    die();
  1074. X}
  1075. X
  1076. XDots(which)    /* which? recovered game, start from command line, or menu */
  1077. Xint which;    /* 0 = start from beginning, 1 = recovered game */
  1078. X{
  1079. X    Upper(Initial[US]);
  1080. X    Lower(Initial[THEM]);
  1081. X
  1082. X    if (mode == TWOPLAYER) {
  1083. X    mvprintw(LINES-5,0, "Your label is '%c' and %s's is '%c'.",
  1084. X                    Initial[US], opponent, Initial[THEM]);
  1085. X    mvprintw(LINES-4,0, "%s will go first.", (mover==US)? "You" : opponent);
  1086. X    mvaddstr(LINES-3,0, "^Z stops game for you only. \"fg\" resumes game.");
  1087. X    mvaddstr(LINES-2,0, "ESC to talk to other player. ^L to redraw board.");
  1088. X    msg("--hit any key to continue-- ");
  1089. X    getchar();
  1090. X    set_redraw_signal_key_to('\014');    /* change to ^L */
  1091. X    free_board();
  1092. X    }
  1093. X    if (!which)        /* could be a restart of a saved game  or  a new game */
  1094. X    setup(), free_board();
  1095. X    drawboard();
  1096. X    while (!board_is_full())
  1097. X    if (mode != DEMO && (mode == TWOPLAYER || mover == US))
  1098. X        mover = (personmove()) ? mover : !mover; /* switch if we got some */
  1099. X    else if (mode != TWOPLAYER && (mode == DEMO || mover == THEM))
  1100. X        if (!board_is_full())
  1101. X        compmove(), mover = !mover;
  1102. X    end_of_game();
  1103. X}
  1104. X
  1105. Xgetopts()
  1106. X{
  1107. X    char *p, *opts, temp[BUFSIZ], *length, *index();
  1108. X
  1109. X    (void) strcpy(prize, PRIZE);
  1110. X    (void) strcpy(save_file, SAVE_FILE);
  1111. X    if (opts = getenv("DOTSOPTS")) {
  1112. X    length = opts + strlen(opts);
  1113. X    while (opts < length) {
  1114. X        (void) sscanf(opts, "%[^,]", temp);
  1115. X        if (p = index(temp, '='))
  1116. X        if (!strncmp(temp, "name", 4))
  1117. X            username = ++p;
  1118. X        else if (!(strncmp(temp, "savefile", 8)))
  1119. X            (void) strcpy(save_file, ++p);
  1120. X        else if (!(strncmp(temp, "prize", 5)))
  1121. X            (void) strcpy(prize, ++p);
  1122. X        else if (!(strncmp(temp, "initial", 7)))
  1123. X            Initial[US] = *++p;
  1124. X        opts += 1 + strlen(temp);
  1125. X    }
  1126. X    }
  1127. X    if (!Initial[US])
  1128. X    Initial[US] = *username;
  1129. X}
  1130. X
  1131. Xparse_command(argc, argv)
  1132. Xint argc;
  1133. Xchar **argv;
  1134. X{
  1135. X    if (!strcmp(argv[1], "2")) {
  1136. X    if (argc < 3)
  1137. X        printf(error_msg, argv[0]);
  1138. X    else
  1139. X#ifdef BSD
  1140. X        mode = TWOPLAYER, sockit(argc, argv);
  1141. X#else
  1142. X            printf(stderr,"Sorry - no sockets, no two player mode\n");
  1143. X#endif /* BSD */
  1144. X    die();
  1145. X    }
  1146. X
  1147. X    mode = INTERACTIVE;
  1148. X
  1149. X    if (!strcmp(argv[1], "-r")) {
  1150. X    if (argc == 3)
  1151. X        (void) strcpy(save_file, argv[2]);
  1152. X    if (recover(1))
  1153. X        Dots(1);
  1154. X    else
  1155. X        die();
  1156. X    menu();
  1157. X    }
  1158. X
  1159. X    if (argc < 4)
  1160. X    do_error(argv[0]);
  1161. X
  1162. X    if ((level = atoi(argv[3])) < DUMB || level > KILLER) {
  1163. X    printf("%s: Invalid Difficulty Level (0,1, or 2)\n", argv[0]);
  1164. X    die();
  1165. X    }
  1166. X    if ((Length = atoi(argv[1])) > MAXL || Length < (level? H_MINL : MINL)) {
  1167. X    printf("%s: (%d) Invalid Length.\n", argv[0], Length);
  1168. X    die();
  1169. X    }
  1170. X    if ((Width = atoi(argv[2])) > MAXW || Width < (level? H_MINW : MINW)) {
  1171. X    printf("%s: (%d) Invalid Width.\n", argv[0], Width);
  1172. X    die();
  1173. X    }
  1174. X
  1175. X    if (argc > 4)
  1176. X    Initial[US] = *argv[4];
  1177. X    comptally = persontally = 0;
  1178. X    xposit = 2, yposit = 1;
  1179. X    y_start = 1 + LINES / 2 - Width;
  1180. X    x_start = 1 + COLS / 2 - Length * 2;
  1181. X    Dots(2);
  1182. X}
  1183. X
  1184. X#include <pwd.h>
  1185. Xchar *
  1186. Xgetusername()
  1187. X{
  1188. X    struct passwd *entry, *getpwuid();
  1189. X    extern char *getlogin();
  1190. X    register char *p;
  1191. X
  1192. X    if ((p = getenv("NAME"))
  1193. X    || (p = getenv("SIGNATURE"))
  1194. X    || (p = getenv("USER"))
  1195. X    || (p = getlogin()))
  1196. X    return p;
  1197. X    if (!(entry = getpwuid(getuid())))
  1198. X    puts("Who the hell are you?"), die();
  1199. X    endpwent();
  1200. X    return entry->pw_name;
  1201. X}
  1202. END_OF_main.c
  1203. if test 5274 -ne `wc -c <main.c`; then
  1204.     echo shar: \"main.c\" unpacked with wrong size!
  1205. fi
  1206. # end of overwriting check
  1207. fi
  1208. if test -f menu.c -a "${1}" != "-c" ; then 
  1209.   echo shar: Will not over-write existing file \"menu.c\"
  1210. else
  1211. echo shar: Extracting \"menu.c\" \(4530 characters\)
  1212. sed "s/^X//" >menu.c <<'END_OF_menu.c'
  1213. X/*    MENU.C    */
  1214. X
  1215. X#include "dots.h"
  1216. X#include <utmp.h>
  1217. X#include <sys/stat.h>
  1218. X
  1219. X#define ever (;;)
  1220. X
  1221. X/* in the function menu() I make it impossible to choose option #7
  1222. X   unless BSD is defined because option #7 is challenge another user,
  1223. X   and that only works under BSD with sockets.
  1224. X   J.M.Libove
  1225. X*/
  1226. Xmenu()
  1227. X{
  1228. X    int c, command = 1;
  1229. X
  1230. X    jmpbuf_set = 1;
  1231. X    disp_menu(setjmp(menu_jmp) < 2);
  1232. X    for ever {
  1233. X    while ((c = getchar()) != '\n')
  1234. X#ifdef BSD
  1235. X        if (c > '0' && c < '9')
  1236. X#else
  1237. X            if (c > '0' && c < '9' && c != '7')
  1238. X#endif /* BSD */
  1239. X        putchar(c), putchar('\b'), command = c;
  1240. X    switch (command - '0') {
  1241. X        case 1: readinst(0), disp_menu(1);
  1242. X        when 2: level = DUMB, mode = INTERACTIVE, Dots(0);
  1243. X        when 3: level = HARD, mode = INTERACTIVE, Dots(0);
  1244. X        when 4: level = KILLER, mode = INTERACTIVE, Dots(0);
  1245. X        when 5: level = DUMB, mode = DEMO, Dots(0);
  1246. X        when 6: if (recover(0)) Dots(1);
  1247. X        when 7: challenge();
  1248. X        when 8: goodbye(1);
  1249. X    }
  1250. X    }
  1251. X}
  1252. X
  1253. Xdisp_menu(clear_it)
  1254. X{
  1255. X    int partition = LINES / 10, lines;
  1256. X
  1257. X    if (clear_it)
  1258. X    clear();
  1259. X    mvaddstr((lines = partition + LINES - 10 * partition), COLS / 2 - 10, ". . . D O T S . . .");
  1260. X    mvaddstr((lines += partition), COLS / 6, "1. Read instructions.");
  1261. X    mvaddstr((lines += partition), COLS / 6, "2. Easy game.");
  1262. X    mvaddstr((lines += partition), COLS / 6, "3. Hard game.");
  1263. X    mvaddstr((lines += partition), COLS / 6, "4. Killer game.");
  1264. X    mvaddstr((lines = partition + LINES - 9 * partition), 4 * COLS / 6, "5. Demo game.");
  1265. X    mvaddstr((lines += partition), 4 * COLS / 6, "6. Recover saved game.");
  1266. X#ifdef BSD
  1267. X    mvaddstr((lines += partition), 4 * COLS / 6, "7. Play someone else.");
  1268. X#else
  1269. X    mvaddstr((lines += partition), 4 * COLS / 6, "7. Only under BSD.");
  1270. X#endif /* BSD */
  1271. X    mvaddstr((lines += partition), 4 * COLS / 6, "8. Leave game.");
  1272. X    mvaddstr((lines += partition), COLS / 2 - 9, "Enter command. [ ]\b\b");
  1273. X    refresh();
  1274. X}
  1275. X
  1276. Xreadinst(before)
  1277. Xbool before;        /* before or after curses mode has been set */
  1278. X{
  1279. X    int c, line_count = 0;
  1280. X    FILE *fp2;
  1281. X
  1282. X    if (!before)
  1283. X    clear(), refresh();
  1284. X    else
  1285. X    noecho(), crmode();
  1286. X    if ((fp2 = fopen(DOCFILE, "r")) == NULL)
  1287. X    perror(DOCFILE);
  1288. X    else {
  1289. X    while ((c = getc(fp2)) != EOF) {
  1290. X        putchar(c);
  1291. X        if (c == '\n')
  1292. X        line_count++;
  1293. X        if (line_count == LINES - 1) {
  1294. X        printf("--more--(or 'q' to return)");
  1295. X        if (getchar() == 'q') {
  1296. X            fclose(fp2);
  1297. X            if (before)
  1298. X            echo(), nocrmode();
  1299. X            return;
  1300. X        }
  1301. X        printf("\015                          \015");
  1302. X        line_count = 0;
  1303. X        }
  1304. X    }
  1305. X    fclose(fp2);
  1306. X    }
  1307. X    if (!before) {
  1308. X    printf("Hit return to continue [ ]\b\b");
  1309. X    while (getchar() != '\n');
  1310. X    } else
  1311. X    echo(), nocrmode();
  1312. X}
  1313. X
  1314. Xwritable(line)
  1315. Xchar *line;
  1316. X{
  1317. X    char ttyno[20];
  1318. X
  1319. X    sprintf(ttyno, "/dev/%s", line);
  1320. X    return !access(ttyno, 02);
  1321. X}
  1322. X
  1323. Xchallenge()
  1324. X{
  1325. X#ifdef BSD
  1326. X    struct utmp buf;
  1327. X    int count = 0, col = LINES / 3, l_len = 0;
  1328. X    char *p, *index(), *victim[4], string[20], *ttyname(), *tty = ttyname(0)+5;
  1329. X    FILE *file;
  1330. X
  1331. X    victim[0] = "Dots";
  1332. X    victim[1] = "2";
  1333. X    clear();
  1334. X    mvaddstr(col, 0, "Here are your potential opponents: ");
  1335. X    move(++col, 0);
  1336. X
  1337. X    if ((file = fopen("/etc/utmp", "r")) == NULL) {
  1338. X    disp_menu(1);
  1339. X    msg("/etc/utmp: %s", sys_errlist[errno]);
  1340. X    return;
  1341. X    }
  1342. X    while (fread((char *)&buf, sizeof(struct utmp), 1, file) > 0)
  1343. X    if (buf.ut_name[0] && writable(buf.ut_line)) {
  1344. X        if (!strncmp(buf.ut_name, username, 8) && !strcmp(buf.ut_line, tty))
  1345. X        continue;
  1346. X        if (count++)
  1347. X        addstr(", ");
  1348. X        if ((l_len + 10 + min(strlen(buf.ut_name), 8)) > COLS - 1)
  1349. X        clrtoeol(), move(++col, 0), l_len = 0;
  1350. X        l_len += 10 + min(strlen(buf.ut_name), 8);
  1351. X        printw("%-.8s (%s)", buf.ut_name, buf.ut_line);
  1352. X    }
  1353. X    (void) fclose(file);
  1354. X    if (!count) {
  1355. X    disp_menu(1);
  1356. X    msg("There doesn't seem to be anyone who can play.");
  1357. X    return;
  1358. X    }
  1359. X    mvaddstr(col += 2, 0, "RETURN for menu.");
  1360. X    mvaddstr(++col, 0, "Whom would you like to play (user [ttyxx])? ");
  1361. X    refresh();
  1362. X    count = 2;
  1363. X    Getstr(string, min(20, COLS - 1));
  1364. X    if (string[0] == NULL) {
  1365. X    disp_menu(1);
  1366. X    return;
  1367. X    }
  1368. X    move(++col, 0);
  1369. X    refresh();
  1370. X    victim[count++] = string;
  1371. X    if ((p = index(string, ' ')) != NULL) {
  1372. X    *(p++) = '\0';
  1373. X    victim[count - 1] = string;
  1374. X    victim[count++] = p;
  1375. X    }
  1376. X    mode = TWOPLAYER;
  1377. X    sockit(count, victim); /* shouldn't return. If so, there was an error */
  1378. X    mode = DEMO;
  1379. X    putchar('\n'); /* don't overwrite any error messages */
  1380. X    msg("Hit any key to continue.");
  1381. X    getchar();
  1382. X    disp_menu(1);
  1383. X#endif /* BSD */
  1384. X}
  1385. END_OF_menu.c
  1386. if test 4530 -ne `wc -c <menu.c`; then
  1387.     echo shar: \"menu.c\" unpacked with wrong size!
  1388. fi
  1389. # end of overwriting check
  1390. fi
  1391. if test -f misc.c -a "${1}" != "-c" ; then 
  1392.   echo shar: Will not over-write existing file \"misc.c\"
  1393. else
  1394. echo shar: Extracting \"misc.c\" \(8465 characters\)
  1395. sed "s/^X//" >misc.c <<'END_OF_misc.c'
  1396. X/*    MISC.C    */
  1397. X
  1398. X#include "dots.h"
  1399. X
  1400. X/* has to be a function instead of define because signal calls this */
  1401. Xredraw()
  1402. X{
  1403. X    clearok(curscr, TRUE), wrefresh(curscr);
  1404. X}
  1405. X
  1406. X/* returns the number of boxes closed, if any */
  1407. Xentermove()
  1408. X{
  1409. X    Cursor(xposit, yposit);
  1410. X    addstr(iseven(yposit) ? "|\b" : "\b---\b\b");
  1411. X    board[xposit][yposit] = USED;
  1412. X    return he_got_some();
  1413. X}
  1414. X
  1415. Xclosure(BorG, x, y)
  1416. Xregister int BorG, x, y;
  1417. X{
  1418. X    if (!is_on_board(x, y))
  1419. X    return (-1);
  1420. X    if (BorG == GOOD)
  1421. X    return (board[x][y - 1]
  1422. X        + board[x][y + 1]
  1423. X        + board[x - 1][y]
  1424. X        + board[x + 1][y]);
  1425. X    else
  1426. X    return (badboard[x][y - 1]
  1427. X        + badboard[x][y + 1]
  1428. X        + badboard[x - 1][y]
  1429. X        + badboard[x + 1][y]);
  1430. X}
  1431. X
  1432. Xhe_got_some()
  1433. X{
  1434. X    int total = 0, x1, y1, x2, y2;
  1435. X
  1436. X    find_adj_squares(xposit, yposit, &x1, &y1, &x2, &y2);
  1437. X    if (closure(GOOD, x1, y1) == 4) {
  1438. X    putinitial(x1, y1, mover);
  1439. X    total++;
  1440. X    }
  1441. X    if (closure(GOOD, x2, y2) == 4) {
  1442. X    putinitial(x2, y2, mover);
  1443. X    total++;
  1444. X    }
  1445. X    if (mover == THEM)
  1446. X    comptally += total;
  1447. X    else
  1448. X    persontally += total;
  1449. X    bottom_line();
  1450. X
  1451. X    return total;
  1452. X}
  1453. X
  1454. Xset_redraw_signal_key_to(c)
  1455. Xchar c;
  1456. X{
  1457. X    static char oldquit = 0;
  1458. X
  1459. X#ifdef TIOCGETC
  1460. X    if (!oldquit)
  1461. X    if (ioctl(0, TIOCGETC, &tchars) == -1)
  1462. X        oops("ioctl get call");
  1463. X    else
  1464. X        oldquit = tchars.t_quitc;
  1465. X    tchars.t_quitc = (c) ? c : oldquit;    /* redraw screen anytime by signal */
  1466. X    if (ioctl(0, TIOCSETC, &tchars) == -1)
  1467. X    oops("ioctl set call");
  1468. X#else
  1469. X    puts("Use your quit key to redraw.");
  1470. X#endif /* TIOCGETC */
  1471. X}
  1472. X
  1473. Xbottom_line()
  1474. X{
  1475. X    char line[128], Opponent[12];
  1476. X    register char *p = line;
  1477. X
  1478. X/* the reason for this (almost) duplication of code is that in every
  1479. X   case where BSD requires 'strlen(sprintf(..' sysV doesn't need the
  1480. X   'strlen' because its return from sprintf is the length...
  1481. X   J.M.Libove
  1482. X*/
  1483. X#ifdef BSD
  1484. X    (void) sprintf(Opponent, "%s's", opponent);
  1485. X    if (mode != DEMO)
  1486. X    p += strlen(sprintf(p, "%8s turn.    ",
  1487. X        (mover == US) ? "Your" : (mode == TWOPLAYER) ? Opponent : "My"));
  1488. X    p += strlen(sprintf(p, "%s: %3d    %s: %3d     ",
  1489. X    (mode == DEMO) ? "Player 1" : "You",
  1490. X    persontally, (mode == TWOPLAYER) ? opponent :
  1491. X    (mode == DEMO) ? "Player 2" : "Me", comptally));
  1492. X    if (mode != TWOPLAYER && mode != DEMO && strlen(line) + 13 < COLS - 1)
  1493. X    p += strlen(sprintf(p, "Level: %s ",
  1494. X        (level == DUMB) ? "EASY" : (level == HARD) ? "HARD" : "KILLER"));
  1495. X    if (p - line + 14 < COLS - 1 && mode != DEMO)
  1496. X    p += strlen(sprintf(p, "   '?' for help."));
  1497. X    if (mode == DEMO)
  1498. X    p += strlen(sprintf(p, "            Demo Game."));
  1499. X    if (mode == TWOPLAYER && p - line + 29 < COLS - 1)
  1500. X    (void) sprintf(p, "  '^L' to redraw.  ESC to talk.");
  1501. X    msg(line);
  1502. X    Cursor(xposit, yposit);
  1503. X#else
  1504. X    (void) sprintf(Opponent, "%s's", opponent);
  1505. X    if (mode != DEMO)
  1506. X    p += sprintf(p, "%8s turn.    ",
  1507. X        (mover == US) ? "Your" : (mode == TWOPLAYER) ? Opponent : "My");
  1508. X    p += sprintf(p, "%s: %3d    %s: %3d     ",
  1509. X    (mode == DEMO) ? "Player 1" : "You",
  1510. X    persontally, (mode == TWOPLAYER) ? opponent :
  1511. X    (mode == DEMO) ? "Player 2" : "Me", comptally);
  1512. X    if (mode != TWOPLAYER && mode != DEMO && strlen(line) + 13 < COLS - 1)
  1513. X    p += sprintf(p, "Level: %s ",
  1514. X        (level == DUMB) ? "EASY" : (level == HARD) ? "HARD" : "KILLER");
  1515. X    if (p - line + 14 < COLS - 1 && mode != DEMO)
  1516. X    p += sprintf(p, "   '?' for help.");
  1517. X    if (mode == DEMO)
  1518. X    p += sprintf(p, "            Demo Game.");
  1519. X    if (mode == TWOPLAYER && p - line + 29 < COLS - 1)
  1520. X    (void) sprintf(p, "  '^L' to redraw.  ESC to talk.");
  1521. X    msg(line);
  1522. X    Cursor(xposit, yposit);
  1523. X#endif /* BSD */
  1524. X}
  1525. X
  1526. Xboard_is_almost_full()
  1527. X{
  1528. X    return (persontally + comptally >= (Length - 1) * (Width - 1) - 4);
  1529. X}
  1530. X
  1531. Xboard_is_full()
  1532. X{
  1533. X    return (persontally + comptally == (Length - 1) * (Width - 1));
  1534. X}
  1535. X
  1536. Xend_of_game()
  1537. X{
  1538. X    char line[80], c;
  1539. X    register char *p = line;
  1540. X
  1541. X/* this (almost) duplication of code is needed because BSD 'sprintf'
  1542. X   returns the address of the string printed, but SysV returns the
  1543. X   number of characters printed, making the 'strlen(' invalid.
  1544. X   J.M.Libove
  1545. X*/
  1546. X#ifdef BSD
  1547. X    move(LINES - 1, 0);
  1548. X    if (board_is_full()) {
  1549. X    p += strlen(sprintf(p, "Score: %d to %d.  ", comptally, persontally));
  1550. X    if (comptally == persontally)
  1551. X        p += strlen(sprintf(p, "No one won.  "));
  1552. X    else if (mode == DEMO)
  1553. X        p += strlen(sprintf(p, "%s won.  ", (comptally > persontally)
  1554. X        ? "Player 2" : "Player 1"));
  1555. X    else
  1556. X        p += strlen(sprintf(p, "%s won.  ",
  1557. X        (comptally > persontally) ? (mode == TWOPLAYER) ?
  1558. X        "They" : "I" : "You"));
  1559. X#else
  1560. X    move(LINES - 1, 0);
  1561. X    if (board_is_full()) {
  1562. X    p += sprintf(p, "Score: %d to %d.  ", comptally, persontally);
  1563. X    if (comptally == persontally)
  1564. X        p += sprintf(p, "No one won.  ");
  1565. X    else if (mode == DEMO)
  1566. X        p += sprintf(p, "%s won.  ", (comptally > persontally)
  1567. X        ? "Player 2" : "Player 1");
  1568. X    else
  1569. X        p += sprintf(p, "%s won.  ",
  1570. X        (comptally > persontally) ? (mode == TWOPLAYER) ?
  1571. X        "They" : "I" : "You");
  1572. X#endif /* BSD */
  1573. X    addstr(line);
  1574. X    if (mode != DEMO)
  1575. X        if (comptally - persontally < 0) {
  1576. X        printw("You get a %s. ", prize);
  1577. X        if (mode != TWOPLAYER)
  1578. X            high_score(0, 0);
  1579. X        } else if (comptally != persontally)
  1580. X        printw("You lose a %s. ", prize);
  1581. X    } else
  1582. X    addstr("No score, you quit.");
  1583. X    Length = Width = 0;
  1584. X    if (mode == TWOPLAYER)
  1585. X    goodbye(1);
  1586. X    addstr("--more--"), clrtoeol();
  1587. X    refresh();
  1588. X    getchar();
  1589. X    if (jmpbuf_set)
  1590. X    msg("RETURN for menu; 'Q' to exit. ");
  1591. X    if (!jmpbuf_set || (c = getchar()) == 'q' || c == 'Q')
  1592. X    goodbye(1);
  1593. X    longjmp(menu_jmp, 1);
  1594. X}
  1595. X
  1596. Xgoodbye(When)
  1597. Xbool When;
  1598. X{
  1599. X    if (When)
  1600. X    msg("");
  1601. X    if (When && mode != TWOPLAYER)
  1602. X    high_score(TRUE, FALSE);
  1603. X    printf("\nThanx, %s.\n", username);
  1604. X    die();
  1605. X}
  1606. X
  1607. X/*VARARGS1*/
  1608. Xmsg(fmt, args)
  1609. Xchar *fmt;
  1610. X{
  1611. X    char string[BUFSIZ];
  1612. X#ifdef VPRINTF
  1613. X    vsprintf(string, fmt, &args);
  1614. X#else
  1615. X    FILE foo;
  1616. X    foo._cnt = BUFSIZ;
  1617. X    foo._base = foo._ptr = string; /* may have to be cast(unsigned char *) */
  1618. X    foo._flag = _IOWRT+_IOSTRG;
  1619. X    _doprnt(fmt, &args, &foo);
  1620. X    (void) fputc(0, &foo);
  1621. X#endif /* VPRINTF */
  1622. X    mvaddstr(LINES-1, 0, string), clrtoeol(), refresh();
  1623. X}
  1624. X
  1625. X/*VARARGS1*/
  1626. Xoops(fmt, args)
  1627. Xchar *fmt;
  1628. X{
  1629. X#ifdef VPRINTF
  1630. X    vprintf(fmt, &args);
  1631. X#else
  1632. X    _doprnt(fmt, &args, stdout);
  1633. X#endif /* VPRINTF */
  1634. X    perror("");
  1635. X}
  1636. X
  1637. Xdie()
  1638. X{
  1639. X    set_redraw_signal_key_to(0);    /* reset to original, whatever it was */
  1640. X#ifdef BSD
  1641. X    if (mode == TWOPLAYER)
  1642. X    destroysocket();
  1643. X#endif /* BSD */
  1644. X    nocrmode(), echo(), endwin();
  1645. X    exit(0);
  1646. X}
  1647. X
  1648. Xonintr(sig)
  1649. X{
  1650. X    int x, y;
  1651. X
  1652. X    (void) signal(sig, onintr);
  1653. X    (void) alarm(0);
  1654. X    if (sig != SIGPIPE) {
  1655. X    getyx(stdscr, y, x);
  1656. X    msg("Really quit? ");
  1657. X    if (getchar() != 'y') {
  1658. X        move(y, x);
  1659. X        if (Length && Width)
  1660. X        bottom_line();
  1661. X        else
  1662. X        refresh();
  1663. X        return;
  1664. X    }
  1665. X    }
  1666. X    msg("");
  1667. X    if (sig != SIGINT && sig != SIGQUIT) {
  1668. X    if (sig == SIGPIPE)
  1669. X#ifdef BSD
  1670. X        destroysocket(), fprintf(stderr, "Your opponent terminated.\n");
  1671. X#else
  1672. X            fprintf (stderr, "Shouldn't have ever got here, but your opponent quit\n");
  1673. X#endif /* BSD */
  1674. X    else
  1675. X#ifdef BSD
  1676. X        printw("I got signal #%d: %s", sig, sys_siglist[sig]);
  1677. X#else
  1678. X            printw("I got signal #%d", sig);
  1679. X#endif /* BSD */
  1680. X    clrtoeol();
  1681. X    refresh();
  1682. X    }
  1683. X    if (jmpbuf_set && sig != SIGINT && sig != SIGQUIT)
  1684. X    longjmp(menu_jmp, 1);
  1685. X    die();
  1686. X}
  1687. X
  1688. XCursor(a, b)
  1689. Xint a, b;
  1690. X{
  1691. X    move(y_start + b - 1, x_start + a * 2 - 2), refresh();
  1692. X}
  1693. X
  1694. Xis_on_board(x, y)
  1695. Xregister int x, y;
  1696. X{
  1697. X    return (x > 0 && y > 0 && x < 2 * Length && y < 2 * Width);
  1698. X}
  1699. X
  1700. Xputinitial(x, y, owner)
  1701. Xregister int x, y, owner;
  1702. X{
  1703. X    Cursor(x, y);
  1704. X    addch(Initial[owner]);
  1705. X    refresh();
  1706. X    board[x][y] = owner;
  1707. X}
  1708. X
  1709. Xshell()
  1710. X{
  1711. X    register char     *SHELL;
  1712. X    register int    pid, w;
  1713. X    int         status, (*oq)(), (*oi)(), (*signal())();
  1714. X
  1715. X    clear(), refresh();
  1716. X    printf("Which Shell, (sh / csh (s/c))? ");
  1717. X    SHELL = (getchar() == 'c') ? "/bin/csh" : "/bin/sh";
  1718. X    echo(), nocrmode();
  1719. X
  1720. X    oi = signal(SIGINT, SIG_IGN);  /* old interrupt (oi) and old quit (oq) */
  1721. X    oq = signal(SIGQUIT, SIG_IGN); /* signals saved on return of signal() */
  1722. X
  1723. X    if ((pid = fork()) == 0) {
  1724. X    setuid(getuid());
  1725. X    setgid(getgid());
  1726. X    execl(SHELL, SHELL, 0);
  1727. X    oops("Couldn't execl(%s)", SHELL);
  1728. X    _exit(127);
  1729. X    }
  1730. X    while ((w = wait(&status)) != pid && w != -1)
  1731. X    ;
  1732. X    printf("[Hit return to continue]");
  1733. X    while (getchar() != '\n')
  1734. X    ;
  1735. X
  1736. X    (void) signal(SIGINT, oi);    /* reset old signals */
  1737. X    (void) signal(SIGQUIT, oq);
  1738. X    noecho(), crmode();
  1739. X    drawboard(), bottom_line();
  1740. X    return (status);
  1741. X}
  1742. END_OF_misc.c
  1743. if test 8465 -ne `wc -c <misc.c`; then
  1744.     echo shar: \"misc.c\" unpacked with wrong size!
  1745. fi
  1746. # end of overwriting check
  1747. fi
  1748. if test -f person.c -a "${1}" != "-c" ; then 
  1749.   echo shar: Will not over-write existing file \"person.c\"
  1750. else
  1751. echo shar: Extracting \"person.c\" \(3829 characters\)
  1752. sed "s/^X//" >person.c <<'END_OF_person.c'
  1753. X/*    PERSON.C    */
  1754. X
  1755. X#include "dots.h"
  1756. X
  1757. X#define ever (;;)
  1758. X
  1759. Xpersonmove()
  1760. X{
  1761. X    char c;
  1762. X    int fd = ((mover == US) ? 0 : sd);
  1763. X
  1764. X    Cursor(xposit, yposit);    /* do this so raw mode won't destroy screen */
  1765. X    raw();
  1766. X    noraw();        /* flush type-ahead */
  1767. X    bottom_line();
  1768. X    do  {
  1769. X    for ever {
  1770. X        if (read(fd, &c, 1) <= 0)
  1771. X        onintr(SIGPIPE);    /* someone terminated */
  1772. X        if (mode == TWOPLAYER)
  1773. X        if (c == '!' || c == 'S' || c == '.' || c == '/' || c == 'Q')
  1774. X            continue;
  1775. X        else if (c != 'r' && fd != sd)
  1776. X            (void) write(sd, &c, 1);    /* send info to other player */
  1777. X        if (c == '\n' || c == ' ')
  1778. X        break;
  1779. X        Cursor(xposit, yposit);
  1780. X        switch (c) {
  1781. X        case ESC:
  1782. X            if (mode == TWOPLAYER)
  1783. X                talk();
  1784. X
  1785. X        when '?':
  1786. X            if (mover == US)
  1787. X            readinst(0), drawboard();
  1788. X            if (mode == TWOPLAYER)
  1789. X            if (mover == THEM) {
  1790. X                msg("%s is reading the instructions.", opponent);
  1791. X                if (read(fd, &c, 1) <= 0)    /* wait for a char */
  1792. X                onintr(SIGPIPE);
  1793. X            } else
  1794. X                (void) write(sd, &c, sizeof(c));
  1795. X            bottom_line();
  1796. X        when '!':
  1797. X            if (shell() == -1)
  1798. X            perror("shell");
  1799. X        when 'Q':
  1800. X            if (mode != TWOPLAYER)
  1801. X            end_of_game();
  1802. X            else
  1803. X            onintr(SIGPIPE);
  1804. X        when 'S': Save_game();
  1805. X        when 'r': redraw();
  1806. X            when '7': case 'q': case 'y':
  1807. X            if (is_on_board(xposit - 1, yposit - 1))
  1808. X                xposit -= 1, yposit -= 1;
  1809. X            when '8': case 'w': case 'k':
  1810. X            if (is_on_board(xposit, yposit - 2))
  1811. X                yposit -= 2;
  1812. X            when '9': case 'e': case 'u':
  1813. X            if (is_on_board(xposit + 1, yposit - 1))
  1814. X                xposit += 1, yposit -= 1;
  1815. X            when '4': case 'a': case 'h':
  1816. X            if (is_on_board(xposit - 2, yposit))
  1817. X                xposit -= 2;
  1818. X            when '6': case 'd': case 'l':
  1819. X            if (is_on_board(xposit + 2, yposit))
  1820. X                xposit += 2;
  1821. X            when '1': case 'z': case 'b':
  1822. X            if (is_on_board(xposit - 1, yposit + 1))
  1823. X                xposit -= 1, yposit += 1;
  1824. X            when '2': case 'x': case 'j':
  1825. X            if (is_on_board(xposit, yposit + 2))
  1826. X                yposit += 2;
  1827. X            when '3': case 'c': case 'n':
  1828. X            if (is_on_board(xposit + 1, yposit + 1))
  1829. X                xposit += 1, yposit += 1;
  1830. X        when '.': chlevel(c);
  1831. X        }
  1832. X        Cursor(xposit, yposit);
  1833. X    }
  1834. X    if (board[xposit][yposit] == USED && mover == US) {
  1835. X        mvaddstr(LINES - 1, 0, "It's taken.   ");
  1836. X        Cursor(xposit, yposit);
  1837. X    }
  1838. X    }
  1839. X    while (board[xposit][yposit] == USED);
  1840. X    return entermove();
  1841. X}
  1842. X
  1843. X#define Addch(c)    addch(c); if (mode == TWOPLAYER) (void) write(sd, &c, 1)
  1844. X#define backspace() Addch(back_char); Addch(space); Addch(back_char); refresh()
  1845. X
  1846. XGetstr(String, length)
  1847. Xchar *String;
  1848. Xint length;
  1849. X{
  1850. X    char garbage, space = ' ', back_char = erase_char;
  1851. X    extern struct sgttyb _tty; /* curses library has this */
  1852. X    int count = 0;
  1853. X
  1854. X    while ((garbage = getchar()) != '\n' && garbage != 4 && garbage != ESC)
  1855. X    if (garbage == _tty.sg_erase && count) {
  1856. X        backspace();
  1857. X        String[count--] = 0;
  1858. X    } else if (garbage == _tty.sg_kill && count)
  1859. X        do {
  1860. X        backspace();
  1861. X        } while (--count);
  1862. X    else if (garbage == '\027' && count)    /* ^W */
  1863. X        do  {
  1864. X        backspace();
  1865. X        String[count--] = 0;
  1866. X        if (!count || (String[count-1]==' ' && !isspace(String[count])))
  1867. X            break;
  1868. X        } while (count);
  1869. X    else if (count == length)
  1870. X        fputc('\007', stderr);
  1871. X    else if (garbage > 31 && garbage != 127) {
  1872. X        String[count++] = garbage;
  1873. X        Addch(garbage);
  1874. X        refresh();
  1875. X    }
  1876. X    String[count] = 0;
  1877. X}
  1878. X
  1879. Xtalk()
  1880. X{
  1881. X    char c, dummy[128], cr = '\n';
  1882. X    int nread = 0;
  1883. X
  1884. X    if (mover == US) {
  1885. X    move(LINES - 3, 15);
  1886. X    clrtoeol(), refresh();
  1887. X    Getstr(dummy, COLS - 16);
  1888. X    (void) write(sd, &cr, 1);
  1889. X    } else {
  1890. X    move(LINES - 2, strlen(opponent) + 3 + strlen("Messages: "));
  1891. X    clrtoeol();
  1892. X    refresh();
  1893. X    while ((nread = read(sd, &c, 1)) > 0 && c != cr)
  1894. X        addch(c), refresh();
  1895. X    if (nread == -1)
  1896. X        oops("bad socket read");
  1897. X    }
  1898. X}
  1899. END_OF_person.c
  1900. if test 3829 -ne `wc -c <person.c`; then
  1901.     echo shar: \"person.c\" unpacked with wrong size!
  1902. fi
  1903. # end of overwriting check
  1904. fi
  1905. if test -f save.c -a "${1}" != "-c" ; then 
  1906.   echo shar: Will not over-write existing file \"save.c\"
  1907. else
  1908. echo shar: Extracting \"save.c\" \(4337 characters\)
  1909. sed "s/^X//" >save.c <<'END_OF_save.c'
  1910. X/*  SAVE.C  */
  1911. X
  1912. X#include "dots.h"
  1913. X
  1914. XSave_game()
  1915. X{
  1916. X    int c;
  1917. X    FILE *fp;
  1918. X    char buf[40];
  1919. X
  1920. X    buf[0] = 0;
  1921. X
  1922. X    msg("File: %s? ", save_file);
  1923. X    if ((c = getchar()) != 'Y' && c != 'y') {
  1924. X    if (c != ESC) {
  1925. X        msg("File: ");
  1926. X        Getstr(buf, min(40, COLS - 8));
  1927. X        if (strlen(buf) > 1)
  1928. X        (void) strcpy(save_file, buf);
  1929. X    }
  1930. X    } else
  1931. X    (void) strcpy(buf, save_file);
  1932. X    if (*buf)
  1933. X    if (!(fp = fopen(buf, "w"))) {
  1934. X        msg("Couldn't open %s: %s --more--", save_file, sys_errlist[errno]);
  1935. X        while (getchar() != ' ')
  1936. X        fputc(7, stderr);
  1937. X    } else {
  1938. X        c = save(fp, SAVE);
  1939. X        (void) fclose(fp);
  1940. X        if (c)
  1941. X        fputc('\n', stdout), die();
  1942. X    }
  1943. X    bottom_line();
  1944. X}
  1945. X
  1946. Xrecover(before)
  1947. Xbool before;
  1948. X{
  1949. X    int c, xspot, yspot;
  1950. X    FILE *fp;
  1951. X
  1952. X    if (!before) {
  1953. X    getyx(stdscr, yspot, xspot);
  1954. X    msg("File: %s? ", save_file);
  1955. X    if ((c = getchar()) != 'Y' && c != 'y')
  1956. X        if (c != ESC) {
  1957. X        char buf[40];
  1958. X        msg("Input Filename: ");
  1959. X        Getstr(buf, min(40, COLS - 17));
  1960. X        move(LINES - 1, 0);
  1961. X        refresh();
  1962. X        if (strlen(buf) < 2) {
  1963. X            move(yspot, xspot);
  1964. X            refresh();
  1965. X            return 0;
  1966. X        } else
  1967. X            (void) strcpy(save_file, buf);
  1968. X        } else
  1969. X        return 0;
  1970. X    }
  1971. X    if (!(fp = fopen(save_file, "r")))
  1972. X    if (before)
  1973. X        perror(save_file);
  1974. X    else
  1975. X        msg("Couldn't open %s: %s", save_file, sys_errlist[errno]);
  1976. X    else if (save(fp, LOAD)) {
  1977. X    (void) fclose(fp);
  1978. X    if (unlink(save_file) < 0)
  1979. X        oops("Couldn't unlink savefile"), puts("Are you trying to cheat?");
  1980. X    return 1;
  1981. X    } else {
  1982. X    (void) fclose(fp);
  1983. X    if (before)
  1984. X        putchar('\n'), die();
  1985. X    }
  1986. X    if (!before)
  1987. X    move(yspot, xspot), refresh();
  1988. X    return 0;
  1989. X}
  1990. X
  1991. Xsave(fp, funct)
  1992. XFILE *fp;
  1993. X{
  1994. X    register int x, y;
  1995. X    int i;
  1996. X
  1997. X    if (funct == LOAD) {
  1998. X    char V[80], *p;
  1999. X
  2000. X    if (fgets(V, 80, fp) && (p = index (V, '\n')))
  2001. X        *p = 0;
  2002. X    if (strcmp(V, version)) {
  2003. X        printf("Sorry, file is wrong version.");
  2004. X        return FALSE;
  2005. X    }
  2006. X        if (fscanf (fp, "persontally = %d\n", &persontally) < 1 ||
  2007. X        fscanf (fp, "comptally = %d\n", &comptally) < 1 ||
  2008. X        fscanf (fp, "Length = %d\n", &Length) < 1 ||
  2009. X        fscanf (fp, "Width = %d\n", &Width) < 1)
  2010. X        goto bad;
  2011. X    for (x = 0; x < Length * 2; ++x)
  2012. X        for (y = 0; y < Width * 2; ++y) {
  2013. X        if (fscanf (fp, "board[%*d][%*d] = %d\n", &i) < 1)
  2014. X            goto bad;
  2015. X        board[x][y] = i;
  2016. X        }
  2017. X        if (fscanf (fp, "xposit = %d\n", &xposit) < 1 ||
  2018. X        fscanf (fp, "yposit = %d\n", &yposit) < 1 ||
  2019. X        fscanf (fp, "x_start = %d\n", &x_start) < 1 ||
  2020. X        fscanf (fp, "y_start = %d\n", &y_start) < 1 ||
  2021. X        fscanf (fp, "no_good_moves = %d\n", &no_good_moves) < 1 ||
  2022. X        fscanf (fp, "control_already_established = %d\n",
  2023. X            &control_already_established) < 1 ||
  2024. X        fscanf (fp, "segtype = %d\n", &segtype) < 1 ||
  2025. X        fscanf (fp, "dX_found = %d\n", &dX_found) < 1 ||
  2026. X        fscanf (fp, "segflag = %d\n", &segflag) < 1 ||
  2027. X        fscanf (fp, "mode = %d\n", &mode) < 1 ||
  2028. X        fscanf (fp, "level = %d\n", &level) < 1 ||
  2029. X        fscanf (fp, "Bingo.x = %d, Bingo.y = %d\n",
  2030. X        &Bingo.x, &Bingo.y) < 2 ||
  2031. X        fscanf (fp, "Initial = %2c\n", Initial) < 1 ||
  2032. X        fscanf (fp, "mover = %d\n", &mover) < 1)
  2033. X        goto bad;
  2034. X    if (Length < 4 || Width < 4) {
  2035. Xbad:
  2036. X        msg("File has been corrupted.");
  2037. X        return FALSE;
  2038. X    }
  2039. X    } else {
  2040. X    (void) fprintf(fp, "%s\n", version);
  2041. X        fprintf (fp, "persontally = %d\n", persontally);
  2042. X        fprintf (fp, "comptally = %d\n", comptally);
  2043. X        fprintf (fp, "Length = %d\n", Length);
  2044. X        fprintf (fp, "Width = %d\n", Width);
  2045. X    for (x = 0; x < Length * 2; ++x)
  2046. X        for (y = 0; y < Width * 2; ++y)
  2047. X        fprintf (fp, "board[%d][%d] = %d\n", x, y, board[x][y]);
  2048. X        fprintf (fp, "xposit = %d\n", xposit);
  2049. X        fprintf (fp, "yposit = %d\n", yposit);
  2050. X        fprintf (fp, "x_start = %d\n", x_start);
  2051. X        fprintf (fp, "y_start = %d\n", y_start);
  2052. X        fprintf (fp, "no_good_moves = %d\n", no_good_moves);
  2053. X        fprintf (fp, "control_already_established = %d\n",
  2054. X              control_already_established);
  2055. X        fprintf (fp, "segtype = %d\n", segtype);
  2056. X        fprintf (fp, "dX_found = %d\n", dX_found);
  2057. X        fprintf (fp, "segflag = %d\n", segflag);
  2058. X        fprintf (fp, "mode = %d\n", mode);
  2059. X        fprintf (fp, "level = %d\n", level);
  2060. X        fprintf (fp, "Bingo.x = %d, Bingo.y = %d\n", Bingo.x, Bingo.y);
  2061. X        fprintf (fp, "Initial = %.2s\n", Initial);
  2062. X        fprintf (fp, "mover = %d\n", mover);
  2063. X    }
  2064. X    return TRUE;
  2065. X}
  2066. END_OF_save.c
  2067. if test 4337 -ne `wc -c <save.c`; then
  2068.     echo shar: \"save.c\" unpacked with wrong size!
  2069. fi
  2070. # end of overwriting check
  2071. fi
  2072. if test -f score.c -a "${1}" != "-c" ; then 
  2073.   echo shar: Will not over-write existing file \"score.c\"
  2074. else
  2075. echo shar: Extracting \"score.c\" \(2371 characters\)
  2076. sed "s/^X//" >score.c <<'END_OF_score.c'
  2077. X/*  SCORE.C  */
  2078. X
  2079. X#include         "dots.h"
  2080. X
  2081. X#define NAMELEN        30
  2082. X
  2083. Xstruct scores {
  2084. X    int sc_person;
  2085. X    int sc_comp;
  2086. X    char sc_name[NAMELEN];
  2087. X    int sc_level;
  2088. X    int sc_width;
  2089. X    int sc_length;
  2090. X    char sc_login[9];
  2091. X}   top_ten[10];
  2092. X
  2093. Xhigh_score(Read, names)
  2094. Xbool Read, names;
  2095. X{
  2096. X    struct scores *scp, *temp;
  2097. X    int fd;
  2098. X
  2099. X    for (scp = top_ten; scp < &top_ten[10]; scp++) {
  2100. X    scp->sc_name[0] = 0;
  2101. X    scp->sc_login[0] = 0;
  2102. X    scp->sc_length = 0;
  2103. X    scp->sc_width = 0;
  2104. X    scp->sc_person = 0;
  2105. X    scp->sc_comp = 0;
  2106. X    scp->sc_level = 0;
  2107. X    }
  2108. X
  2109. X    /* read the top ten file into the array and close the file */
  2110. X    if ((fd = open(SCOREFILE, 2)) < 0) {
  2111. X    printf("no score file\n");
  2112. X    return;
  2113. X    }
  2114. X    (void) read(fd, (char *) top_ten, sizeof(top_ten));
  2115. X
  2116. X    /* Print the list */
  2117. X    if (Read) {
  2118. X    printf("Top Players:\n");
  2119. X    printf("Level\tDimensions   Computer   Human\tName\n");
  2120. X    for (scp = top_ten; scp < &top_ten[10]; scp++)
  2121. X        if (scp->sc_person) {
  2122. X        printf("%s\t  %2d X %2d      %3d       %3d\t%s",
  2123. X            (scp->sc_level == DUMB) ?
  2124. X            "Easy" : (scp->sc_level == HARD ?
  2125. X            "Hard" : "Killer"),
  2126. X            scp->sc_width,
  2127. X            scp->sc_length, scp->sc_comp, scp->sc_person, scp->sc_name);
  2128. X        if (names)
  2129. X            printf("(%s)", scp->sc_login);
  2130. X        putchar('\n');
  2131. X        } else
  2132. X        break;
  2133. X    }
  2134. X    /* check to see if current score made it */
  2135. X    else {
  2136. X    for (scp = top_ten; scp < &top_ten[10]; scp++)
  2137. X        if (value_cmp(scp))
  2138. X        break;
  2139. X    if (scp < &top_ten[10]) {
  2140. X        char *getlogin(), *login = getlogin();
  2141. X
  2142. X        for (temp = &top_ten[9]; temp > scp; temp--)
  2143. X        *temp = *(temp - 1);
  2144. X        scp->sc_width = Width;
  2145. X        scp->sc_length = Length;
  2146. X        scp->sc_person = persontally;
  2147. X        scp->sc_comp = comptally;
  2148. X        scp->sc_level = level;
  2149. X        (void) strcpy(scp->sc_login, login);
  2150. X        addstr("--more--"), clrtoeol();
  2151. X        refresh();
  2152. X        raw(), noraw();
  2153. X        while (getchar() != ' ')
  2154. X        fputc(7, stderr);
  2155. X        msg("You made the top ten! Enter a name: ");
  2156. X        Getstr(scp->sc_name, NAMELEN - 1);
  2157. X        if (strlen(scp->sc_name) > 1) {
  2158. X        (void) lseek(fd, (long)0, 0);
  2159. X        (void) write(fd, (char *)top_ten, sizeof top_ten);
  2160. X        } else
  2161. X        msg("Nothing entered.");
  2162. X    }
  2163. X    (void) close(fd);
  2164. X    }
  2165. X}
  2166. X
  2167. Xvalue_cmp(entry)
  2168. Xstruct scores *entry;
  2169. X{
  2170. X    int value;
  2171. X
  2172. X    value = (level - entry->sc_level) * 500;
  2173. X    value += persontally + Length * Width;
  2174. X    return (value > entry->sc_length * entry->sc_width + entry->sc_person);
  2175. X}
  2176. END_OF_score.c
  2177. if test 2371 -ne `wc -c <score.c`; then
  2178.     echo shar: \"score.c\" unpacked with wrong size!
  2179. fi
  2180. # end of overwriting check
  2181. fi
  2182. if test -f sockt.c -a "${1}" != "-c" ; then 
  2183.   echo shar: Will not over-write existing file \"sockt.c\"
  2184. else
  2185. echo shar: Extracting \"sockt.c\" \(4229 characters\)
  2186. sed "s/^X//" >sockt.c <<'END_OF_sockt.c'
  2187. X/* sockt.c */
  2188. X/* All the stuff that deals with sockets is here */
  2189. X
  2190. X#include "dots.h"
  2191. X#include <sys/un.h>    /* unix domain sockets */
  2192. X#include <errno.h>
  2193. X
  2194. X#define SOCKNAME  "/tmp/dots"
  2195. X
  2196. X#define namelen(sockt) (sizeof (sockt.sun_family) + strlen(sockt.sun_path))
  2197. X
  2198. Xint len;
  2199. Xstatic int (*oldint)(), (*oldquit)();
  2200. Xstruct sockaddr_un sockt;
  2201. X
  2202. Xsockit(argc, argv)
  2203. Xchar **argv;
  2204. X{
  2205. X    setbuf(stdout, (char *)NULL);
  2206. X
  2207. X    mover = THEM;
  2208. X    opponent = argv[2];
  2209. X    Initial[THEM] = *opponent;
  2210. X
  2211. X    (void) strcpy(sockt.sun_path, SOCKNAME);
  2212. X    len = namelen(sockt);
  2213. X
  2214. X    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {    /* create a socket */
  2215. X    oops("Socket error");
  2216. X    return;
  2217. X    }
  2218. X
  2219. X    /* try to respond to a possible connection already established */
  2220. X    while (connect(sd, (struct sockaddr *)&sockt, namelen(sockt)) == -1)
  2221. X    /*
  2222. X     * check to see if we can't connect because of "correct" errors 
  2223. X     */
  2224. X    if (errno != ENOENT) {    /* no such file or directory */
  2225. X        perror("connect on socket");
  2226. X        puts("Trying again...");
  2227. X        (void) close(sd);
  2228. X        sockit(argc, argv);
  2229. X    } else {
  2230. X        mover = US;    /* challenger goes first */
  2231. X        if (!findem(argc, argv))
  2232. X        return;
  2233. X        else
  2234. X        break;
  2235. X    }
  2236. X    getsizes();        /* get the window sizes of both players */
  2237. X    Dots(2);        /* we are connected and won't return */
  2238. X}
  2239. X
  2240. X/* send an invitation */
  2241. X
  2242. X#include <sys/time.h>
  2243. Xstruct itimerval waittime;
  2244. Xjmp_buf jmpbuf;
  2245. X
  2246. Xreinvite(sig)
  2247. X{
  2248. X    if (sig == SIGALRM) {
  2249. X    printf("\nre");
  2250. X    longjmp(jmpbuf, 1);
  2251. X    }
  2252. X    timerclear(&waittime.it_interval);
  2253. X    timerclear(&waittime.it_value);
  2254. X    (void) setitimer(ITIMER_REAL, &waittime, (struct itimerval *) 0);
  2255. X    destroysocket();
  2256. X    (void) signal(SIGINT, oldint);
  2257. X    (void) signal(SIGQUIT, oldquit);
  2258. X    longjmp(jmpbuf, 2);
  2259. X}
  2260. X
  2261. Xinvite(recipient)
  2262. XFILE *recipient;
  2263. X{
  2264. X    int newsok;
  2265. X
  2266. X    waittime.it_value.tv_sec = 30;
  2267. X    waittime.it_value.tv_usec = 0;
  2268. X    waittime.it_interval = waittime.it_value;
  2269. X
  2270. X    /*
  2271. X     * we're a server, so we give a name to the socket to the client knows
  2272. X     * what to connect with. bind() is used to give a name to a socket. 
  2273. X     */
  2274. X    if (bind(sd, (struct sockaddr *)&sockt, len) == -1) {
  2275. X    oops("Can't bind %s", SOCKNAME);
  2276. X    return 0;
  2277. X    }
  2278. X    if (listen(sd, 5) == -1) {
  2279. X    oops("Can't listen %s", SOCKNAME);
  2280. X    return 0;
  2281. X    }
  2282. X
  2283. X    setbuf(recipient, (char *)NULL);
  2284. X
  2285. X    /*
  2286. X     * accept() will hang around and do nothing unless someone requests a
  2287. X     * connection.  So, we wait..  signal again every 30 secs with setitmer 
  2288. X     */
  2289. X    (void) signal(SIGALRM, reinvite);
  2290. X    oldint = signal(SIGINT, reinvite);
  2291. X    oldquit = signal(SIGQUIT, reinvite);
  2292. X    (void) setitimer(ITIMER_REAL, &waittime, (struct itimerval *) 0);
  2293. X    if (setjmp(jmpbuf) == 2)
  2294. X    return 0;
  2295. X    printf("sending challenge...");
  2296. X    fprintf(recipient, "Message from the \"dots\" game...\007\007\007\n");
  2297. X    fprintf(recipient, "%s would like to play \"dots.\"\n", username);
  2298. X    fprintf(recipient, "respond with \"dots 2 %s\"\n", username);
  2299. X
  2300. X    while ((newsok = accept(sd, (struct sockaddr *)0, (int *)0)) == -1)
  2301. X    if (errno != EINTR) {
  2302. X        oops("Can't accept %s", SOCKNAME);
  2303. X        return 0;
  2304. X    } else
  2305. X        continue;
  2306. X
  2307. X    timerclear(&waittime.it_interval);
  2308. X    timerclear(&waittime.it_value);
  2309. X    (void) setitimer(ITIMER_REAL, &waittime, (struct itimerval *) 0);
  2310. X    (void) close(sd);
  2311. X    sd = newsok;
  2312. X    return 1;
  2313. X}
  2314. X
  2315. X /* find lines and cols of the other guy */
  2316. Xgetsizes()
  2317. X{
  2318. X    int their_lines, their_cols;
  2319. X
  2320. X    do_twice {
  2321. X    if (mover == US) {
  2322. X        (void) write(sd, (char *)&COLS, sizeof(int));
  2323. X        (void) write(sd, (char *)&LINES, sizeof(int));
  2324. X    } else {
  2325. X        (void) read(sd, (char *)&their_cols, sizeof(int));
  2326. X        (void) read(sd, (char *)&their_lines, sizeof(int));
  2327. X    }
  2328. X    mover = !mover;
  2329. X    }
  2330. X    Length = min(COLS, their_cols) / 4;
  2331. X    Width = min(LINES, their_lines) / 2 - 2;
  2332. X    comptally = persontally = 0;
  2333. X    xposit = 2, yposit = 1;
  2334. X    y_start = 1 + (LINES - 2) / 2 - Width;
  2335. X    x_start = 1 + COLS / 2 - Length * 2;
  2336. X
  2337. X    (void) signal(SIGINT, oldint);
  2338. X    (void) signal(SIGQUIT, oldquit);
  2339. X}
  2340. X
  2341. Xdestroysocket()
  2342. X{
  2343. X    if (!access(SOCKNAME, 0)) {
  2344. X    if (shutdown(sd, 2) == -1)  /* dissallow further sends and recieves */
  2345. X        oops("shutdown failed cuz");
  2346. X    if (unlink(SOCKNAME) == -1)
  2347. X        oops("Can't unlink %s", SOCKNAME);
  2348. X    }
  2349. X}
  2350. END_OF_sockt.c
  2351. if test 4229 -ne `wc -c <sockt.c`; then
  2352.     echo shar: \"sockt.c\" unpacked with wrong size!
  2353. fi
  2354. # end of overwriting check
  2355. fi
  2356. echo shar: End of shell archive.
  2357. exit 0
  2358.